import CryptoJS from 'crypto-js'

const SECRET_KEY = 'system@2025'

class CryptoUtils {
  constructor() {
    this.secretKey = SECRET_KEY
  }

  encrypt(data, key = this.secretKey) {
    try {
      const dataStr = typeof data === 'object' ? JSON.stringify(data) : String(data)
      const encrypted = CryptoJS.AES.encrypt(dataStr, key).toString()
      return encrypted
    } catch (error) {
      console.error('加密失败:', error)
      throw new Error('数据加密失败')
    }
  }

  decrypt(encryptedData, key = this.secretKey) {
    try {
      const bytes = CryptoJS.AES.decrypt(encryptedData, key)
      const decryptedStr = bytes.toString(CryptoJS.enc.Utf8)

      if (!decryptedStr) {
        throw new Error('解密失败，可能是密钥错误')
      }

      // 尝试解析为JSON对象，如果不是JSON则返回字符串
      try {
        return JSON.parse(decryptedStr)
      } catch {
        return decryptedStr
      }
    } catch (error) {
      console.error('解密失败:', error)
      throw new Error('数据解密失败')
    }
  }

  /**
   * MD5 哈希（不可逆）
   * @param {string} data - 要哈希的数据
   * @returns {string} MD5哈希值
   */
  md5(data) {
    return CryptoJS.MD5(data).toString()
  }

  /**
   * SHA256 哈希（不可逆）
   * @param {string} data - 要哈希的数据
   * @returns {string} SHA256哈希值
   */
  sha256(data) {
    return CryptoJS.SHA256(data).toString()
  }

  /**
   * Base64 编码
   * @param {string} data - 要编码的数据
   * @returns {string} Base64编码字符串
   */
  base64Encode(data) {
    return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data))
  }

  /**
   * Base64 解码
   * @param {string} data - Base64编码字符串
   * @returns {string} 解码后的字符串
   */
  base64Decode(data) {
    return CryptoJS.enc.Base64.parse(data).toString(CryptoJS.enc.Utf8)
  }

  /**
   * 安全存储到 localStorage
   * @param {string} key - 存储键名
   * @param {any} value - 存储值
   */
  setEncryptedStorage(key, value) {
    try {
      const encrypted = this.encrypt(value)
      localStorage.setItem(key, encrypted)
      return true
    } catch (error) {
      console.error('安全存储失败:', error)
      return false
    }
  }

  /**
   * 从 localStorage 安全读取
   * @param {string} key - 存储键名
   * @returns {any} 解密后的值
   */
  getEncryptedStorage(key) {
    try {
      const encrypted = localStorage.getItem(key)
      if (!encrypted) return null

      return this.decrypt(encrypted)
    } catch (error) {
      console.error('安全读取失败:', error)
      return null
    }
  }

  /**
   * 移除安全存储
   * @param {string} key - 存储键名
   */
  removeEncryptedStorage(key) {
    localStorage.removeItem(key)
  }

  /**
   * 生成随机字符串（可用于盐值）
   * @param {number} length - 字符串长度
   * @returns {string} 随机字符串
   */
  generateRandomString(length = 16) {
    return CryptoJS.lib.WordArray.random(length).toString()
  }

  /**
   * 带盐值的加密（更安全）
   * @param {string} data - 要加密的数据
   * @param {string} salt - 盐值
   * @returns {object} 包含加密数据和盐值的对象
   */
  encryptWithSalt(data, salt = this.generateRandomString()) {
    const saltedData = data + salt
    const encrypted = this.encrypt(saltedData)
    return {
      data: encrypted,
      salt: salt
    }
  }

  /**
   * 带盐值的解密
   * @param {string} encryptedData - 加密数据
   * @param {string} salt - 盐值
   * @returns {string} 解密后的数据
   */
  decryptWithSalt(encryptedData, salt) {
    const decryptedWithSalt = this.decrypt(encryptedData)
    return decryptedWithSalt.replace(salt, '')
  }
}

// 创建单例实例
const cryptoUtils = new CryptoUtils()

export default cryptoUtils